
#include <string>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;

#define FIFO_PATH "./"
#define FIFO_NAME "pipe"

#define ERR_EXIT(x)  \
    do               \
    {                \
        perror(x);   \
        exit(errno); \
    } while (0);

class namedpipe_creat
{
public:
    namedpipe_creat(string pathname) : _pathname(pathname)
    {
        // 创建管道文件
        if (mkfifo(_pathname.c_str(), 0666) == -1)
            ERR_EXIT("mkfifo");
    }
    ~namedpipe_creat()
    {
        // 删除管道文件
        if (unlink(_pathname.c_str()) == -1)
            ERR_EXIT("mistake");
    }

private:
    string _pathname;
};

class namedpipe_operator
{
public:
    namedpipe_operator(string pathname, int flags) : _pathname(pathname)
    {
        // 打开管道文件
        fd = open(pathname.c_str(), flags);
        if (fd == -1)
            ERR_EXIT("open");
    }

    void Read()
    {
        // 读取客户端信息
        int cnt = 0;
        while (true)
        {
            sleep(2);
            char buffer[1024] = {0};
            int ret = read(fd, buffer, sizeof(buffer) - 1);
            if (ret == 0)
                break;
            else if (ret == -1)
                ERR_EXIT("read");
            printf("client say#%s-第%d次接受-客户端编号%d:\n", buffer, ++cnt, getpid());
        }
    }

    void Write()
    {
        // 向服务端发送信息
        while (true)
        {
            string buffer;
            cout << "send serve#";
            getline(cin, buffer);
            if (write(fd, buffer.c_str(), buffer.size()) == -1)
                ERR_EXIT("write");
        }
    }

    ~namedpipe_operator()
    {
        // 关闭管道文件
        close(fd);
    }

private:
    string _pathname;
    int fd;
};